package com.dragon.concurrent.demo.waitnotify;

import org.omg.PortableServer.THREAD_POLICY_ID;

import javax.swing.text.html.Option;
import java.util.*;
import java.util.concurrent.locks.Lock;

public class CaptureService {

    private static final int MAX_SIZE = 5;

    private static volatile LinkedList<Thread> pool = new LinkedList<>();

    private static final Object LOCK = new Object();

    public static void main(String[] args) {
        List<Thread> workers = new ArrayList<>();
        Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10")
                .stream()
                .map(CaptureService::createCaptureThread)
                .forEach(t -> {
                    t.start();
                    workers.add(t);
                });
        workers.stream()
                .forEach(thread -> {
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
        Optional.of("All of capture work finished").ifPresent(System.out::println);
    }

    public static Thread createCaptureThread(String name) {
        return new Thread(() -> {
            Optional.of("The worker [" + Thread.currentThread().getName() + "] begin capture data !")
                    .ifPresent(System.out::println);
            synchronized (LOCK) {
                while (pool.size() >= MAX_SIZE) {
                    try {
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                pool.add(Thread.currentThread());
            }
            Optional.of("thw worker [" + Thread.currentThread().getName() + "] is working !")
                    .ifPresent(System.out::println);
            try {
                // 模拟工作 5 秒
                Thread.sleep(5_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (LOCK) {
                Optional.of("The worker [" + Thread.currentThread().getName() + "] end capture data !")
                        .ifPresent(System.out::println);
                pool.remove(Thread.currentThread());
                LOCK.notifyAll();
            }
        }, name);
    }
}
